/* ASTTracer 
 * 
 * An object response for tracing an AST. 
 * 
 * 
 */
package ast;


import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MemberRef;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;

import astStatData.ElementMap;

public class ASTTracer extends ASTVisitor{
	private ASTStatData statDataSet;
	private ElementMap map;

	public ASTTracer(ElementMap m){
		map = m;
		statDataSet = new ASTStatData();
	}
	
	/* For Assignment
	 * e.g: i = 0;
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Assignment)
	 */
	public boolean visit(Assignment node){
		statDataSet.addAssignmentNum();
		System.out.println( statDataSet.getAssignmentNum()+"th Assignment, left: " + node.getLeftHandSide() );
		System.out.println( "              , right: " + node.getRightHandSide() +"\n" );
		return true;
		
	}
	
	
	public boolean visit(MethodDeclaration node) {
		statDataSet.addMethodDeclarationNum();
		System.out.print(statDataSet.getMethodDeclarationNum()+"th method, name:");
		System.out.println( node.getName() );
		System.out.println( node.getBody() );
		
		return true;
	}
	
	public boolean visit(ImportDeclaration node){
		statDataSet.addImportDeclarationNum();
		System.out.println( statDataSet.getImportDeclarationCounterNum()
				+"th ImportDeclaration: "  + node);
		return true;
		
	}
	
	
	public boolean visit(ClassInstanceCreation node){

		statDataSet.addClassInstanceCreationNum();
		System.out.println( statDataSet.getClassInstanceCreationNum()
				+"th ClassInstanceCreation: " + node.getType()+": " +node );
		return true;
	}
	
	public boolean visit(FieldDeclaration node){
		statDataSet.addFieldDeclarationNum();
		System.out.println(statDataSet.getFieldDeclarationNum()+"th , FieldDeclaration: " 
							+ node.getType() + ": " + node 
							+"Is PrimitiveType?: "+ node.getType().isPrimitiveType());
		return true;
	}

	public boolean visit(FieldAccess node){
		IVariableBinding b = node.resolveFieldBinding();
//		ASTNode n = map.get(b.getKey());
		
		
		
		statDataSet.addFieldAccessNum();
		System.out.println( statDataSet.getFieldAccessNum()+"th , FieldAccess: " 
							+ node.getName() );
		return true;
	}
	
	public boolean visit(SingleVariableDeclaration node){
		node.resolveBinding();
//		map.put(node.resolveBinding().getKey(), node);
		
		statDataSet.addSingleVariableDeclarationNum();
		System.out.println( statDataSet.getSingleVariableDeclarationNum()+"th , SingleVariableDeclaration: " 
							+ node.getName() + ":" +  node.getType());
		return true;
	} 

	
	public boolean visit(MemberRef node){
		statDataSet.addMemberRefNum();
		System.out.println( statDataSet.getMemberRefNum()+"th , MemberRef: " 
							+ node.getName() );
		return true;
		
	} 
	
    public boolean visit(ExpressionStatement node){
    	System.out.println(node.toString());
		return true;
		
	}
	
	public boolean visit(MethodInvocation node){
		statDataSet.addMethodInvocationNum();
					
		System.out.println( statDataSet.getMethodInvocationNum()
							+"th , MethodInvocation: " +node.getExpression()
							+ " "
							+ node.getName() );
		return true;
	}

/*	
	public boolean visit(SimpleName node){
		statDataSet.addSimpleNameNum();
		System.out.println( statDataSet.getSimpleNameNum()+"th , SimpleName: " 
							+ node.getIdentifier() );
		return true;	
	}  
*/
	
	public void postVisit(ASTNode node){
		if(node instanceof MethodDeclaration)
			System.out.println("trace method " + statDataSet.getMethodDeclarationNum() 
								+ " end." 
								+ "\n=======================" );
		else if(node instanceof CompilationUnit){
			dumpStatData();
			System.out.println("--------------------END TRACE--------------------");
		}
	}
	
	public void dumpStatData(){
		System.out.println("total report: ");
		
		System.out.println("");
	}

}
